using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using spaceattack.Helpers;

namespace spaceattack.GameObjects
{
    class GameManager
    {
        private Ship ship;
        private List<Star> stars;
        private List<Asteroid> asteroids;
        private List<Bullet> bullets;
        private List<Enemy> enemies;

        private DateTime lastShootTime = DateTime.MinValue;

        private int playerScore;

        public GameManager()
        {
           

            ship = new Ship(new Vector2(SpaceAttackGame.Width / 2, SpaceAttackGame.Height - 85), 0.5f);

            stars = new List<Star>();
            asteroids = new List<Asteroid>();
            bullets = new List<Bullet>();
            enemies = new List<Enemy>();

        }

        public void Update()
        {
            UpdateStars();
            
            UpdateAsteroids();

            UpdateBullets();

            UpdateEnemies();

            ship.Update();
        }
        public void ShipShoot()
        {
            if ((DateTime.Now - lastShootTime).Milliseconds > 100)
            {
                AudioManager.PlayShootSound();
                bullets.Add(new Bullet(ship.Position, 0.05f, ShooterEnum.Player));
                lastShootTime = DateTime.Now;
            }
        }

        public void MoveShip(int dx, int dy)
        {
            ship.Move(dx, dy);
        }

        private void UpdateEnemies()
        {
            foreach (Enemy enemy in enemies)
            {
                enemy.Update();
                if (enemy.ReadyToShoot)
                {
                    AudioManager.PlayShootSound();
                    bullets.Add(new Bullet(enemy.Position, 0.035f, ShooterEnum.Computer));
                }

                if (enemy.Rectangle.Intersects(ship.Rectangle))
                {
                    DestroyPlayerShip();
                    enemy.Alive = false;
                }
            }

            int i = 0;
            while (i < enemies.Count)
            {
                if (!enemies[i].OnScreen || !enemies[i].Alive)
                    enemies.RemoveAt(i);
                else i++;
            }

            int r = RandomHelper.Next(4000);
            if (r < 10)
            {
                // choose strat
                EnemyStrategy strategy = (RandomHelper.Next(2) == 0) ? EnemyStrategy.Simple : EnemyStrategy.Advanced;
                int x = RandomHelper.Next(SpaceAttackGame.Width);
                for (int j = 0; j < 6; j++)
                    enemies.Add(new Enemy(new Vector2(x, -50 * (j + 1)), 0.5f, strategy));
            }
        }

        private void UpdateAsteroids()
        {
            foreach (Asteroid asteroid in asteroids)
            {
                asteroid.Update();
                #region collision
                if (asteroid.Rectangle.Intersects(ship.Rectangle))
                {
                    DestroyPlayerShip();
                    asteroid.Alive = false;
                }
                #endregion
            }

            int i = 0;
            while (i < asteroids.Count)
            {
                if (!asteroids[i].OnScreen || !asteroids[i].Alive)
                    asteroids.RemoveAt(i);
                else i++;
            }


            if (RandomHelper.Next(100) < 3)
                asteroids.Add(new Asteroid(new Vector2(RandomHelper.Next(SpaceAttackGame.Width), -40), 0.7f));
        }

        private void UpdateStars()
        {
            foreach (Star star in stars)
            {
                star.Update();
            }

            int i = 0;
            while (i < stars.Count)
            {
                if (!stars[i].OnScreen)
                    stars.RemoveAt(i);
                else i++;
            }

            // add some new stars
            for (int j = 0; j < RandomHelper.Next(5); j++)
            {
                stars.Add(new Star(new Vector2(RandomHelper.Next(SpaceAttackGame.Width), 0), 1 / (float)RandomHelper.Next(5, 11)));
            }
        }

        private void UpdateBullets()
        {
            foreach (Bullet bullet in bullets)
            {
                bullet.Update();
                foreach (Asteroid asteroid in asteroids)
                {
                    if (bullet.Owner == ShooterEnum.Player && asteroid.Rectangle.Intersects(bullet.Rectangle))
                    {
                        asteroid.Alive = false;
                        bullet.Alive = false;
                        playerScore += 10;

                    }
                }

                foreach (Enemy enemy in enemies)
                {
                    if (bullet.Owner == ShooterEnum.Player && enemy.Rectangle.Intersects(bullet.Rectangle))
                    {
                        enemy.Alive = false;
                        bullet.Alive = false;
                        playerScore += 70;
                    }
                }
                if (bullet.Owner == ShooterEnum.Computer && bullet.Rectangle.Intersects(ship.Rectangle))
                {
                    DestroyPlayerShip();
                    bullet.Alive = false;
                }

            }
            int i = 0;
            while (i < bullets.Count)
            {
                if (!bullets[i].OnScreen || !bullets[i].Alive)
                    bullets.RemoveAt(i);
                else i++;
            }
        }

        private void DestroyPlayerShip()
        {
            ship.Place(SpaceAttackGame.Width / 2, SpaceAttackGame.Height - 85);
        }

        #region draw
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Begin(SpriteSortMode.Texture, BlendState.AlphaBlend);

            #region stars
            foreach (Star star in stars)
            {
                star.Draw(spriteBatch);
            }
            #endregion

            #region asteroids
            foreach (Asteroid asteroid in asteroids)
            {
                asteroid.Draw(spriteBatch);
            }
            #endregion

            #region bullets
            foreach (Bullet bullet in bullets)
            {
                bullet.Draw(spriteBatch);
            }
            #endregion

            #region enemy
            foreach (Enemy enemy in enemies)
            {
                enemy.Draw(spriteBatch);
            }
            #endregion

            ship.Draw(spriteBatch);

            #region score
            spriteBatch.DrawString(LoadHelper.Fonts[FontEnum.Arial22],
                                    "Score:" + playerScore.ToString(),
                                   new Vector2(0, 0), Color.White);
            #endregion

            spriteBatch.End();


        }
        #endregion
    }
}
